import React, { Component } from 'react';
import {
  Row,
  Col,
  Card,
  Input,
  Select,
  Icon,
  Button,
  Dropdown,
  InputNumber,
  DatePicker,
  Tooltip
} from 'antd';
import styles from './index.less';
import { connect } from 'dva';
import { getValFromObj } from '@/utils/tools';
import { isFunction } from 'util';

const DEF_VAL = {"无选择": ""};
const DEF_SP = 3;

/**
 * 高级检索(目前和高级表连用)
 * 本检索有两种触发查询的方式：
 * 1. 通过设置更大的更新数触发相同检索条件的查询
 * 2. 通过点击查询按钮触发不同检索条件的查询
 * 
 * @author 戴舒原 2019-03-01
 */
@connect(({ search }) => ({ search }))
export default class AdvancedSearch extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isExtent: false,
      downloadFlag: false,
      selectDic: {},
    };
    this.order = null;                      // 排序方式
    this.items = this.props.items;          // 配置列表
    this.master = this.props.master;        // 主表
    this.outterRef = this.props.outterRef;  // 外键引用
    this.updateCount = 0;                    // 立即刷新标志
    if (!this.master || !Array.isArray(this.items)) {
      throw new Error("searcher initiation has many errors.");
    }
  }

  componentDidMount = () => {
    const { dispatch } = this.props;
    // 从数据库中拉取选项数据 - 仅拉取一次，防止请求陷入死循环
    for (let item of this.items) {
      if (item.type.indexOf("combo") >= 0) {
        if (item.async) {
          item.async.then(dic => {
            let nextDic = {
              ...this.state.selectDic,
              [item.key]: dic
            };
            this.setState({selectDic: nextDic});
          });
        } else if (item.dic) {
          // static dictionary with no actions
        } else {
          dispatch({
            type: "search/componentSelects",
            payload: {
              datatable: item.datatable,
              column: item.key
            }
          });
        }
      } 
    }
  }

  // 填充可选项
  genComboSelect = (dic) => {
    const Option = Select.Option;
    let cache = [];
    for (let key in dic) {
      cache.push(<Option value={dic[key]}>{key}</Option>);
    }
    return cache;
  }

  genBindValuesChange = (item) => {
    // 利用Moment对象对日期进行格式化
    const dateProc = (e) => {
      if (item.format && item.format !== "#") {
        return e.format(item.format);
      } else {
        return e._d.getTime() + "";
      }
    }
    // 将改动的值暂存在item的cache中
    return (e) => {
      item.cache = undefined;
      switch(item.type) {
        case "date":
          item.cache = e? dateProc(e): undefined;
          break;
        case "range_date":
          item.cache = (e && e.length > 0)? [dateProc(e[0]), dateProc(e[1])]: undefined;
          break;
        case "input":
          item.cache = (e && e.currentTarget)? e.currentTarget.value: undefined;
          break;
        default:
          item.cache = e;
          break;
      }
    }
  }

  // 获取下拉字典
  procCols = (item) => {
    if (item.dic) {
      return item.dic;
    } else if(this.state.selectDic[item.key]) {
      return this.state.selectDic[item.key];
    } else if (this.props.search[item.key]) {
      return this.props.search[item.key];
    }
    return {};
  }

  genSelector = (item, props = {}) => {
    // 得到选择栏目数据
    let selects = this.procCols(item);
    selects = {...DEF_VAL, ...selects};
    return (<Select
      style={{ maxWidth: "100%", minWidth: "100%" }}
      {...props}
      defaultValue={item.value? item.value: ""}
      onChange={this.genBindValuesChange(item)}>
      {this.genComboSelect(selects)}
    </Select>);
  }

  // 产生高级检索控件
  generateAdvancedSreach = (items) => {
    let cache = [];
    for (let item of items) {
      if (item.first || this.state.isExtent) {
        let controller = "";
        switch (item.type) {
          case "input":
            controller = (<Input 
              defaultValue={item.value} 
              allowClear 
              onChange={this.genBindValuesChange(item)} 
            />);
            break;
          case "date":
            controller = (<DatePicker onChange={this.genBindValuesChange(item)} />);
            break;
          case "range_date":
            const { RangePicker } = DatePicker;
            controller = (<RangePicker onChange={this.genBindValuesChange(item)} />);
            break;
          case "search_combo":
            controller = this.genSelector(item, {
              showSearch: true,
              placeholder: "请输入内容",
              optionFilterProp: "children"
            });
            break;
          case "muti_combo":
            controller = this.genSelector(item, {
              mode: "multiple"
            });
            break;
          case "combo":
            controller = this.genSelector(item);
            break;
          default:
            console.error(`无法识别的参数类型：${item.type}`);
            break;
        }
        let cols = parseInt(24 / DEF_SP), 
            nums = parseInt((item.name.length + 4) / 3);  // 动态计算文本列宽
        cache.push(<Col xs={24} sm={12} md={12} lg={12} xl={nums} className={styles.topBlank}>{item.name}：</Col>);
        cache.push(<Col xs={24} sm={12} md={12} lg={12} xl={cols - nums} className={styles.topBlank}>{controller} </Col>);
      }
    }
    return cache;
  }

  // 初始化控件
  initController = () => {
    let cache = [], items, advance = this.items.filter(x => !x.first).length;
    if (this.state.isExtent) {
      items = this.items;
    } else {
      items = this.items.filter(x => x.first);
    }
    for (let i=0, len = items.length; i < len; i += DEF_SP) {
      cache.push(<Row type="flex" align="middle" gutter="12">
        {this.generateAdvancedSreach(items.slice(i, i + DEF_SP))}
        {/* 生成查询和高级扩展按钮 */}
        {i + DEF_SP >= len ?
          <Col xs={24} sm={12} md={12} lg={12} xl={6} className={styles.topBlank}>
            <Button loading={this.state.downloadFlag} onClick={() => this.queryNow("searchBtn")} type="primary">
              {!this.state.downloadFlag ? <Icon type="search" /> : ""}查询</Button>&nbsp;
              {advance ? 
                <Tooltip title="检索高级选项">
                  <Button icon={this.state.isExtent ? "caret-down" : "caret-up"} 
                          onClick={() => {
                    this.items.forEach(x => !x.first && (x.isExtent = !this.state.isExtent));
                    this.setState({ isExtent: !this.state.isExtent });
                  }}></Button>
                </Tooltip> : ""}
          </Col> : ""}
      </Row>);
    }
    return cache;
  }

  // 触发查询
  queryNow = (activeObj) => {
    const { dispatch } = this.props;
    this.setState({downloadFlag: true});
    let conditions = [];
    let outterRef = Array.isArray(this.outterRef)? this.outterRef: [];
    let order = this.order? this.order: {};
    for(let item of this.items) {
      // 只有点击查询按钮时才填充检索条件
      if (activeObj === "searchBtn") {
        item.value = item.cache;
      }
      if (item.datatable && 
          (item.first || this.state.isExtent) &&
          item.key && 
          item.value) {
        conditions.push({
          dataTable: item.datatable,
          name: item.key,
          value: item.value,
          mode: item.mode? item.mode: 0
        });
      }
    }
    let searchConds = {
      datatable: this.master,    // 主表名称
      conditions: conditions,    // 查询条件
      relations: outterRef,      // 外键引用
      order: order,              // 排序字段
      pageNum: this.pageNum,     // 页码
      pageSize: this.pageSize    // 页大小
    };
    if (isFunction(this.props.beforeCallback)) {
      this.props.beforeCallback(activeObj, searchConds);
    }
    dispatch({
      type: "search/searchData",
      payload: searchConds,
      callback: (res) => {
        if (isFunction(this.props.callback)) {
          this.props.callback(res.RESULT, res.COUNT, activeObj);
        }
        this.setState({downloadFlag: false});
      }
    });
  }

  render() {
    // 报数游戏-当组件接收一个比上一次的更新数字更大的数字时触发刷新
    // 让组件的刷新状态持续变更，防止拉取数据出现死循环
    if (this.props.updateCount > this.updateCount) {
      // 页码、页大小排序、必须能通过渲染进行改变
      if (this.props.orderField) {
        this.order = {
          field: this.props.orderField,
          mode: this.props.orderMode
        };                                        // 排序标志
      } else {
        this.order = {};                        // 无排序
      }
      this.pageNum = this.props.pageNum;          // 页码
      this.pageSize = this.props.pageSize;        // 页内元素数目
      this.updateCount = this.props.updateCount;  // 刷新数
      this.queryNow("renderer");                  // 立即请求数据
    }
    return this.initController();
  }
}
